package ynu.edu.achitectureclass.service;

import org.springframework.core.io.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.UrlResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import ynu.edu.achitectureclass.entity.CameraData;
import ynu.edu.achitectureclass.entity.Device;
import ynu.edu.achitectureclass.entity.AccessToken;
import ynu.edu.achitectureclass.repository.CameraDataRepository;
import ynu.edu.achitectureclass.repository.DeviceRepository;
import ynu.edu.achitectureclass.repository.AccessTokenRepository;

import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class CameraDataService {

    @Value("${image.storage.path}") // 从配置文件中读取图片存储路径
    private String imageStoragePath;

    @Autowired
    private CameraDataRepository cameraDataRepository;

    @Autowired
    private DeviceRepository deviceRepository;

    @Autowired
    private AccessTokenRepository accessTokenRepository;

    @Autowired
    private RestTemplate restTemplate;

    // 获取 accessToken
    public String getAccessToken() {
        Optional<AccessToken> latestToken = accessTokenRepository.findTopByOrderByCreatedAtDesc();
        if (latestToken.isPresent() && !isTokenExpired(latestToken.get())) {
            return latestToken.get().getToken();
        }

        // 如果 token 过期或不存在，重新获取
        Map<String, String> tokenResponse = callLoginApi();
        String newToken = tokenResponse.get("accessToken");
        long expireTime = Long.parseLong(tokenResponse.get("expireTime"));

        // 存储新的 token
        AccessToken accessToken = new AccessToken();
        accessToken.setToken(newToken);
        accessToken.setExpireTime(expireTime);
        accessToken.setCreatedAt(LocalDateTime.now());
        accessTokenRepository.save(accessToken);

        return newToken;
    }

    // 检查 token 是否过期
    private boolean isTokenExpired(AccessToken accessToken) {
        long expireTime = accessToken.getExpireTime();
        long currentTime = System.currentTimeMillis();
        return currentTime >= expireTime;
    }

    // 调用萤石云登录接口
    private Map<String, String> callLoginApi() {
        String url = "http://42.193.14.241:7000/ysapi/subAccount/getToken";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 请求体
        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("accountId", "1ca7f0ab24ba41b291346347ec30140e");

        HttpEntity<Map<String, String>> request = new HttpEntity<>(requestBody, headers);
        ResponseEntity<Map> response = restTemplate.postForEntity(url, request, Map.class);

        // 解析响应
        Map<String, Object> responseBody = response.getBody();
        Map<String, Object> data = (Map<String, Object>) responseBody.get("data");

        Map<String, String> result = new HashMap<>();
        result.put("accessToken", data.get("accessToken").toString());
        result.put("expireTime", data.get("expireTime").toString());

        return result;
    }

    // 抓拍并保存照片
    public void captureAndSaveImage(String deviceSerial) {
        String accessToken = getAccessToken(); // 获取 accessToken
        System.out.println("accessToken:" + accessToken);
        String imageUrl = callCaptureApi(deviceSerial, accessToken); // 调用抓拍接口
        System.out.println(imageUrl);

        // 查询设备信息
        Optional<Device> deviceOptional = deviceRepository.findBySerialNumber(deviceSerial);
        System.out.println(deviceOptional);
        if (!deviceOptional.isPresent()) {
            throw new RuntimeException("设备不存在: " + deviceSerial);
        }

        // 下载图片并保存到本地
        String localImagePath = saveImageToLocal(imageUrl);

        // 存储抓拍照片
        CameraData cameraData = new CameraData();
        cameraData.setDevice(deviceOptional.get()); // 设置关联的设备
        cameraData.setImageUrl(imageUrl); // 设置抓拍照片的 URL
        cameraData.setLocalImagePath(localImagePath); // 设置本地路径
        cameraData.setCreatedAt(LocalDateTime.now()); // 设置抓拍时间
        cameraDataRepository.save(cameraData); // 保存到数据库
    }

    // 调用萤石云抓拍接口
    private String callCaptureApi(String deviceSerial, String accessToken) {
        // 请求 URL，包含查询参数
        String url = "https://open.ys7.com/api/lapp/device/capture";

        // 使用 UriComponentsBuilder 构建带查询参数的 URL
        String requestUrl = UriComponentsBuilder.fromHttpUrl(url)
                .queryParam("accessToken", accessToken)
                .queryParam("deviceSerial", deviceSerial)
                .queryParam("channelNo", "1")
                .queryParam("quality", "1")
                .toUriString();

        // 发送 GET 请求
        ResponseEntity<Map> response = restTemplate.exchange(requestUrl, HttpMethod.POST, null, Map.class);

        // 解析响应
        Map<String, Object> responseBody = response.getBody();
        if (responseBody != null && responseBody.get("data") != null) {
            Map<String, Object> data = (Map<String, Object>) responseBody.get("data");
            return data.get("picUrl").toString();  // 返回抓拍图片的 URL
        }

        // 如果没有获取到有效数据，返回 null 或错误信息
        return null;
    }

    // 下载图片并保存到本地
    private String saveImageToLocal(String imageUrl) {
        try {
            // 获取项目根目录
            Path projectRoot = Paths.get("").toAbsolutePath();
            Path storagePath = projectRoot.resolve(imageStoragePath); // 转换为绝对路径

            // 创建存储目录（如果不存在）
            if (!Files.exists(storagePath)) {
                Files.createDirectories(storagePath);
            }

            // 生成唯一的文件名
            String fileName = "image_" + System.currentTimeMillis() + ".jpg";
            Path filePath = storagePath.resolve(fileName);

            // 下载图片
            URL url = new URL(imageUrl);
            Resource resource = new UrlResource(url);
            FileCopyUtils.copy(resource.getInputStream(), Files.newOutputStream(filePath));

            // 返回本地路径（绝对路径）
            return filePath.toString();
        } catch (IOException e) {
            throw new RuntimeException("保存图片失败: " + e.getMessage(), e);
        }
    }

    public List<CameraData> getAllCameraData() {
        return cameraDataRepository.findAll();  // 如果使用 JPA
    }
}